package com.raysun.androidbase.service

import android.Manifest
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.os.IBinder
import android.os.Looper
import android.os.Message
import android.os.Messenger
import android.os.Process
import android.os.ResultReceiver
import android.util.Log
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.raysun.androidbase.databinding.ActivityServiceBinding
import com.raysun.androidbase.service.extension.BinderService
import com.raysun.androidbase.service.extension.DataAnalyseService
import com.raysun.androidbase.service.extension.MessengerService
import kotlin.random.Random

class ServiceActivity : AppCompatActivity() {

    private lateinit var binding: ActivityServiceBinding

    private var handler: Handler = Handler(Looper.getMainLooper()) {
        true
    }

    private val resultReceiver = object : ResultReceiver(handler) {
        override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
            val person = resultData?.getString("person")
            Log.d("Raysunshine", "onReceiveResult: $resultCode - $person")
        }
    }

    private val notificationPermission =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) {
                val intent = Intent(this, DataAnalyseService::class.java).apply {
                    putExtra("result_receiver", resultReceiver)
                }
                startForegroundService(intent)
            } else {
                Toast.makeText(applicationContext, "开启前台服务需要通知权限", Toast.LENGTH_LONG)
                    .show()
            }
        }

    private lateinit var binderService: BinderService

    private var isServiceBinding = false

    private val binderServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
            val localBinder = binder as BinderService.LocalBinder
            binderService = localBinder.getService()
            isServiceBinding = true
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            isServiceBinding = false
        }
    }

    private var messengerHandler: MessengerHandler? = null

    private class MessengerHandler(looper: Looper) : Handler(looper) {
        override fun handleMessage(msg: Message) {
            Log.d("Raysunshine", "收到MessengerService发来的消息 : ${msg.what}")
        }
    }

    private var messenger: Messenger? = null

    private val messengerServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
            messenger = Messenger(binder)
            val message = Message.obtain().apply {
                what = 990923
            }
            message.replyTo = Messenger(messengerHandler)
            messenger?.send(message)
        }

        override fun onServiceDisconnected(name: ComponentName?) {

        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityServiceBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.startForegroundService.setOnClickListener {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                checkSinglePermission(Manifest.permission.POST_NOTIFICATIONS, onGranted = {
                    val intent = Intent(this, DataAnalyseService::class.java).apply {
                        putExtra("result_receiver", resultReceiver)
                    }
                    startService(intent)
                }, shouldShowRationale = {
                    Toast.makeText(
                        applicationContext,
                        "开启前台服务需要通知权限",
                        Toast.LENGTH_LONG
                    ).show()
                }, onOtherCase = {
                    notificationPermission.launch(Manifest.permission.POST_NOTIFICATIONS)
                })
            }

        }

        binding.bindBinderService.setOnClickListener {
            Intent(this, BinderService::class.java).also { intent ->
                bindService(intent, binderServiceConnection, Context.BIND_AUTO_CREATE)
            }
        }

        binding.getBindingBinderServiceData.setOnClickListener {
            if (isServiceBinding) {
                binderService.connectedTimes.also {
                    Log.d("Raysunshine", "connectedTimes $it")
                }
            }
        }

        binding.unbindBinderService.setOnClickListener {
            unbindService(binderServiceConnection)
            isServiceBinding = false
        }

        HandlerThread("MessengerThread", Process.THREAD_PRIORITY_BACKGROUND).apply {
            start()

            messengerHandler = MessengerHandler(looper)
        }
        binding.bindMessengerService.setOnClickListener {
            Intent(this, MessengerService::class.java).also {
                bindService(it, messengerServiceConnection, Context.BIND_AUTO_CREATE)
            }
        }

        binding.communicateWithMessengerService.setOnClickListener {
            Message.obtain().apply {
                what = Random.nextInt(100)
            }.let {
                messenger?.send(it)
            }
        }

        binding.unbindMessengerService.setOnClickListener {
            unbindService(messengerServiceConnection)
        }

    }

    private fun checkSinglePermission(
        permission: String,
        onGranted: () -> Unit,
        shouldShowRationale: () -> Unit,
        onOtherCase: () -> Unit,
    ) {
        when {
            ContextCompat.checkSelfPermission(
                applicationContext,
                permission
            ) == PackageManager.PERMISSION_GRANTED -> onGranted()

            ActivityCompat.shouldShowRequestPermissionRationale(
                this@ServiceActivity,
                permission
            ) -> shouldShowRationale()

            else -> onOtherCase()
        }
    }


}